﻿using System;

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
//using System.Web.Security;


    public class EncryptUtils
    {

        /// <summary>
        /// 查找到\uXXXX或\/的位置，返回\字符的索引，没找到返回-1
        /// </summary>
        /// <param name="str"></param>
        /// <param name="start"></param>
        /// <returns></returns>
        static int GetUnicodeCharIndex(string str, int start = 0)
        {
            if (str == null || str.Length < 6) return -1;
            for (int i = start; i + 1 < str.Length; i++)
            {
                if (str[i] != '\\') continue;
                i++;
                if (str[i] == '/')
                    return i - 1;
                if (str[i] != 'u' || i + 4 >= str.Length) continue;
                i++;
                if (str[i] < '0' || (str[i] > '9' && str[i] < 'A') || (str[i] > 'F' && str[i] < 'a') || str[i] > 'f')
                    continue;
                i++;
                if (str[i] < '0' || (str[i] > '9' && str[i] < 'A') || (str[i] > 'F' && str[i] < 'a') || str[i] > 'f')
                    continue;
                i++;
                if (str[i] < '0' || (str[i] > '9' && str[i] < 'A') || (str[i] > 'F' && str[i] < 'a') || str[i] > 'f')
                    continue;
                i++;
                if (str[i] < '0' || (str[i] > '9' && str[i] < 'A') || (str[i] > 'F' && str[i] < 'a') || str[i] > 'f')
                    continue;
                return i - 5;
            }
            return -1;
        }

        /// <summary>
        /// 解码js的unicode字符
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        static public string DecodeJsUnicoe(string str)
        {
            if (string.IsNullOrEmpty(str)) return str;
            int idx = GetUnicodeCharIndex(str);
            if (idx >= 0)
            {
                int last_idx=0;
                StringBuilder sb = new StringBuilder();
                do
                {
                    int ret = 0;
                    int j;
                    if (str[idx + 1] == '/') //找到的是\/
                    {
                        ret = '/';
                        j = idx + 2;
                    }  //找到的是\uXXXX
                    else
                    {
                        int i = idx + 2;
                        j= i + 4;
                        while (i < j)
                        {
                            char c = str[i++];
                            if (c >= '0' && c <= '9') ret = (ret << 4) | (c - '0');
                            else if (c >= 'A' && c <= 'F') ret = (ret << 4) | (c - 'A' + 10);
                            else if (c >= 'a' && c <= 'f') ret = (ret << 4) | (c - 'a' + 10);
                        }
                    }
                    sb.Append(str, last_idx, idx - last_idx);
                    last_idx = j;
                    sb.Append((char)ret);
                } while ((idx = GetUnicodeCharIndex(str, last_idx)) >= 0);
                sb.Append(str, last_idx,str.Length-last_idx);
                return sb.ToString();
            }
            else
                return str;
        }

        /// <summary> 
        /// AES加密 
        /// </summary>
        public static string AESEncrypt(string value, string _aeskey)
        {
            byte[] keyArray = Encoding.UTF8.GetBytes(_aeskey);
            keyArray = new MD5CryptoServiceProvider().ComputeHash(keyArray);

            byte[] toEncryptArray = Encoding.UTF8.GetBytes(value);

            RijndaelManaged rDel = new RijndaelManaged();
            rDel.Key = keyArray;
            rDel.Mode = CipherMode.ECB;
            rDel.Padding = PaddingMode.PKCS7;

            ICryptoTransform cTransform = rDel.CreateEncryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

            return Convert.ToBase64String(resultArray, 0, resultArray.Length);
        }

        /// <summary> 
        /// AES解密 
        /// </summary>
        public static string AESDecrypt(string value, string _aeskey)
        {
            try
            {

                byte[] keyArray = Encoding.UTF8.GetBytes(_aeskey);
                if (keyArray.Length != 16)
                    keyArray = new MD5CryptoServiceProvider().ComputeHash(keyArray);
                byte[] toEncryptArray = Convert.FromBase64String(value);

                

                RijndaelManaged rDel = new RijndaelManaged();
                rDel.Key = keyArray;
                rDel.Mode = CipherMode.ECB;
                rDel.Padding = PaddingMode.PKCS7;

                ICryptoTransform cTransform = rDel.CreateDecryptor();
                byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

                return Encoding.UTF8.GetString(resultArray);
            }
            catch
            {
                return string.Empty;
            }
        }

        /// <summary> 
        /// DES加密 
        /// </summary>
        public static string DESEncrypt(string value, string _deskey)
        {

            byte[] keyArray = Encoding.UTF8.GetBytes(_deskey);
            byte[] toEncryptArray = Encoding.UTF8.GetBytes(value);

            DESCryptoServiceProvider rDel = new DESCryptoServiceProvider();
            rDel.Key = keyArray;
            rDel.Mode = CipherMode.ECB;
            rDel.Padding = PaddingMode.PKCS7;

            ICryptoTransform cTransform = rDel.CreateEncryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

            return Convert.ToBase64String(resultArray, 0, resultArray.Length);
        }

        /// <summary> 
        /// DES解密 
        /// </summary>
        public static string DESDecrypt(string value, string _deskey)
        {
            try
            {

                byte[] keyArray = Encoding.UTF8.GetBytes(_deskey);
                byte[] toEncryptArray = Convert.FromBase64String(value);

                DESCryptoServiceProvider rDel = new DESCryptoServiceProvider();
                rDel.Key = keyArray;
                rDel.Mode = CipherMode.ECB;
                rDel.Padding = PaddingMode.PKCS7;

                ICryptoTransform cTransform = rDel.CreateDecryptor();
                byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

                return Encoding.UTF8.GetString(resultArray);
            }
            catch
            {
                return string.Empty;
            }
        }

        public static string MD5(string value)
        {
            byte[] result = Encoding.UTF8.GetBytes(value);
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] output = md5.ComputeHash(result);
            return BitConverter.ToString(output).Replace("-", "");
        }

        public static string HMACMD5(string value, string hmacKey)
        {
            HMACSHA1 hmacsha1 = new HMACSHA1(Encoding.UTF8.GetBytes(hmacKey));
            byte[] result = System.Text.Encoding.UTF8.GetBytes(value);
            byte[] output = hmacsha1.ComputeHash(result);


            return BitConverter.ToString(output).Replace("-", "");
        }

        /// <summary>
        /// base64编码
        /// </summary>
        /// <returns></returns>
        public static string Base64Encode(string value)
        {
            string result = Convert.ToBase64String(Encoding.Default.GetBytes(value));
            return result;
        }

        /// <summary>
        /// base64解码
        /// </summary>
        /// <returns></returns>
        public static string Base64Decode(string value)
        {
            string result = Encoding.Default.GetString(Convert.FromBase64String(value));
            return result;
        }


    }
